package com.eastfair.file.service.impl;

import cn.hutool.core.util.StrUtil;
import com.eastfair.file.props.MinioConfig;
import com.eastfair.file.service.FileService;
import com.eastfair.file.vo.FileVO;
import com.eastfair.util.OrderUtil;
import io.minio.*;
import io.minio.errors.*;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


/**
 * 文件上传
 */
@Slf4j
@Setter
public class MinioFileServiceImpl implements FileService {

    private MinioConfig config;

    private MinioClient client;

    @Value("${file.subfix.verify}")
    private Boolean subfixVerify;

    /**
     * 本地文件上传
     * @param
     * @return
     */
    @Override
    public FileVO uploadFile(MultipartFile multipartFile, String  bucketName) throws Exception {
        log.info("localPutFile - minio文件上传, bucketName={}", bucketName);
        return uploadFile(multipartFile, bucketName, null);
    }

    @Override
    public FileVO uploadFile(MultipartFile multipartFile, String bucketName, String isMobile) throws Exception {
        // 文件扩展名
        String subfix = null;
        // 原始文件名，不带扩展名
        String rowFilename = null;
        String originalFilename = multipartFile.getOriginalFilename();
        // 系统生成文件名
        String fileName = OrderUtil.getOrderNo("WJ");
        if (originalFilename != null && StrUtil.isNotBlank(originalFilename)) {
            subfix = originalFilename.lastIndexOf(".") == -1 ? originalFilename : originalFilename.substring(originalFilename.lastIndexOf("."));
            rowFilename = originalFilename.lastIndexOf(".") == -1 ? originalFilename : originalFilename.substring(0, originalFilename.lastIndexOf("."));
            fileName = fileName + subfix;
        }
        if (subfixVerify && (StrUtil.isBlank(isMobile) || !"true".equals(isMobile))) {
            // 验证扩展名
            FileService.verifySubFix(subfix);
            // 文件扩展名与文件格式是否一致
            FileService.verifyFileRowSubFix(subfix, multipartFile);
        }
        // 创建bucket
        creatBucket(bucketName);
        // 文件上传
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                .contentType(multipartFile.getContentType())
                .build();
        client.putObject(args);
        String path = config.getAccessUrl() + "/" + bucketName + "/" + fileName;
        FileVO fileVO = new FileVO();
        fileVO.setPath(path);
        fileVO.setFileName(rowFilename);
        fileVO.setSize(multipartFile.getSize() / 1024);
        fileVO.setSubfix(subfix);
        return fileVO;
    }

    /**
     * 创建桶
     * @return
     */
    private  void  creatBucket(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        BucketExistsArgs btest = BucketExistsArgs
                .builder()
                .bucket(bucket)
                .build();
        boolean isExist = client.bucketExists(btest);
        String policyJson = "{\n" +
                "\t\"Version\": \"2012-10-17\",\n" +
                "\t\"Statement\": [{\n" +
                "\t\t\"Effect\": \"Allow\",\n" +
                "\t\t\"Principal\": {\n" +
                "\t\t\t\"AWS\": [\"*\"]\n" +
                "\t\t},\n" +
                "\t\t\"Action\": [\"s3:GetBucketLocation\", \"s3:ListBucket\", \"s3:ListBucketMultipartUploads\"],\n" +
                "\t\t\"Resource\": [\"arn:aws:s3:::" + bucket + "\"]\n" +
                "\t}, {\n" +
                "\t\t\"Effect\": \"Allow\",\n" +
                "\t\t\"Principal\": {\n" +
                "\t\t\t\"AWS\": [\"*\"]\n" +
                "\t\t},\n" +
                "\t\t\"Action\": [\"s3:AbortMultipartUpload\", \"s3:DeleteObject\", \"s3:GetObject\", \"s3:ListMultipartUploadParts\", \"s3:PutObject\"],\n" +
                "\t\t\"Resource\": [\"arn:aws:s3:::" + bucket + "/*\"]\n" +
                "\t}]\n" +
                "}\n";
        if(!isExist){
            MakeBucketArgs build = MakeBucketArgs
                    .builder()
                    .bucket(bucket)
                    .build();
            client.makeBucket(build);
            client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(policyJson).build());
        }
    }

}
